home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / macos / uae069b2.src.cpt.hqx / UAE069ß2.SRC.CPT / uae069fl2.src / cia.c < prev    next >
C/C++ Source or Header  |  1997-06-13  |  19KB  |  812 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * CIA chip support
  5.   *
  6.   * Copyright 1995 Bernd Schmidt, Alessandro Bissacco
  7.   * Copyright 1996, 1997 Stefan Reinauer, Christian Schmitt
  8.   */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12. #include <assert.h>
  13.  
  14. #include "config.h"
  15. #include "options.h"
  16. #include "gensound.h"
  17. #include "sounddep/sound.h"
  18. #include "events.h"
  19. #include "my_memory.h"
  20. #include "custom.h"
  21. #include "cia.h"
  22. #include "serial.h"
  23. #include "disk.h"
  24. #include "xwin.h"
  25. #include "keybuf.h"
  26. #include "gui.h"
  27.  
  28. #define DIV10 5 /* Yes, a bad identifier. */
  29.  
  30. /* battclock stuff */
  31. #define RTC_D_ADJ      8
  32. #define RTC_D_IRQ      4
  33. #define RTC_D_BUSY     2
  34. #define RTC_D_HOLD     1
  35. #define RTC_E_t1       8
  36. #define RTC_E_t0       4
  37. #define RTC_E_INTR     2
  38. #define RTC_E_MASK     1
  39. #define RTC_F_TEST     8
  40. #define RTC_F_24_12    4
  41. #define RTC_F_STOP     2
  42. #define RTC_F_RSET     1
  43.  
  44. static unsigned int clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
  45. static unsigned int clock_control_e = 0;
  46. static unsigned int clock_control_f = RTC_F_24_12;
  47.  
  48. unsigned int ciaaicr,ciaaimask,ciabicr,ciabimask;
  49. unsigned int ciaacra,ciaacrb,ciabcra,ciabcrb;
  50. unsigned long ciaata,ciaatb,ciabta,ciabtb;
  51. unsigned long ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
  52. int ciaatlatch,ciabtlatch;
  53.  
  54. static unsigned long ciaala,ciaalb,ciabla,ciablb;
  55. static int ciaatodon, ciabtodon;
  56. static unsigned int ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr;
  57. static unsigned int ciabpra,ciabprb,ciabdra,ciabdrb,ciabsdr; 
  58. static int div10;
  59. static int kbstate, kback, ciaasdr_unread = 0;
  60.  
  61. static int prtopen;
  62. static FILE *prttmp;
  63.  
  64. static void setclr(unsigned int *p, unsigned int val)
  65. {
  66.     if (val & 0x80) {
  67.     *p |= val & 0x7F;
  68.     } else {
  69.     *p &= ~val;
  70.     }
  71. }
  72.  
  73. static void RethinkICRA(void)
  74. {
  75.     if (ciaaimask & ciaaicr) {
  76.     ciaaicr |= 0x80;
  77.     custom_bank.wput(0xDFF09C,0x8008);
  78.     } else {
  79.     ciaaicr &= 0x7F;
  80. /*    custom_bank.wput(0xDFF09C,0x0008);*/
  81.     }
  82. }
  83.  
  84. static void RethinkICRB(void)
  85. {
  86. #if 0 /* ??? What's this then? */
  87.     if (ciabicr & 0x10) {
  88.     custom_bank.wput(0xDFF09C,0x9000);
  89.     }
  90. #endif
  91.     if (ciabimask & ciabicr) {
  92.     ciabicr |= 0x80;
  93.     custom_bank.wput(0xDFF09C,0xA000);
  94.     } else {
  95.     ciabicr &= 0x7F;
  96. /*    custom_bank.wput(0xDFF09C,0x2000);*/
  97.     }
  98. }
  99.  
  100. static int lastdiv10;
  101.  
  102. static void CIA_update(void)
  103. {
  104.     unsigned long int ccount = cycles - eventtab[ev_cia].oldcycles + lastdiv10;
  105.     unsigned long int ciaclocks = ccount / DIV10;
  106.  
  107.     int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
  108.  
  109.     lastdiv10 = div10;
  110.     div10 = ccount % DIV10;
  111.     
  112.     /* CIA A timers */
  113.     if ((ciaacra & 0x21) == 0x01) {
  114.     assert((ciaata+1) >= ciaclocks);
  115.     if ((ciaata+1) == ciaclocks) {
  116.         aovfla = 1;
  117.         if ((ciaacrb & 0x61) == 0x41) {
  118.         if (ciaatb-- == 0) aovflb = 1;        
  119.         }
  120.     }         
  121.     ciaata -= ciaclocks;
  122.     }
  123.     if ((ciaacrb & 0x61) == 0x01) {
  124.     assert((ciaatb+1) >= ciaclocks);
  125.     if ((ciaatb+1) == ciaclocks) aovflb = 1;
  126.     ciaatb -= ciaclocks;
  127.     }
  128.     
  129.     /* CIA B timers */
  130.     if ((ciabcra & 0x21) == 0x01) {
  131.     assert((ciabta+1) >= ciaclocks);
  132.     if ((ciabta+1) == ciaclocks) {
  133.         bovfla = 1;
  134.         if ((ciabcrb & 0x61) == 0x41) {
  135.         if (ciabtb-- == 0) bovflb = 1;
  136.         }
  137.     } 
  138.     ciabta -= ciaclocks;
  139.     }
  140.     if ((ciabcrb & 0x61) == 0x01) {
  141.     assert ((ciabtb+1) >= ciaclocks);
  142.     if ((ciabtb+1) == ciaclocks) bovflb = 1;
  143.     ciabtb -= ciaclocks;
  144.     }
  145.     if (aovfla) {
  146.     ciaaicr |= 1; RethinkICRA();
  147.     ciaata = ciaala;
  148.     if (ciaacra & 0x8) ciaacra &= ~1;
  149.     }
  150.     if (aovflb) {
  151.     ciaaicr |= 2; RethinkICRA();
  152.     ciaatb = ciaalb;
  153.     if (ciaacrb & 0x8) ciaacrb &= ~1;
  154.     }
  155.     if (bovfla) {
  156.     ciabicr |= 1; RethinkICRB();
  157.     ciabta = ciabla;
  158.     if (ciabcra & 0x8) ciabcra &= ~1;
  159.     }
  160.     if (bovflb) {
  161.     ciabicr |= 2; RethinkICRB();
  162.     ciabtb = ciablb;
  163.     if (ciabcrb & 0x8) ciabcrb &= ~1;
  164.     }
  165. }
  166.  
  167. static void CIA_calctimers(void)
  168. {
  169.     int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
  170.  
  171.     eventtab[ev_cia].oldcycles = cycles;
  172.     
  173.     if ((ciaacra & 0x21) == 0x01) {
  174.     ciaatimea = (DIV10-div10) + DIV10*ciaata;    
  175.     }
  176.     if ((ciaacrb & 0x61) == 0x41) {
  177.     /* Timer B will not get any pulses if Timer A is off. */
  178.     if (ciaatimea >= 0) {
  179.         /* If Timer A is in one-shot mode, and Timer B needs more than
  180.          * one pulse, it will not underflow. */
  181.         if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
  182.         /* Otherwise, we can determine the time of the underflow. */
  183.         ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
  184.         }
  185.     }
  186.     }
  187.     if ((ciaacrb & 0x61) == 0x01) {
  188.     ciaatimeb = (DIV10-div10) + DIV10*ciaatb;
  189.     }
  190.  
  191.     if ((ciabcra & 0x21) == 0x01) {
  192.     ciabtimea = (DIV10-div10) + DIV10*ciabta;    
  193.     }
  194.     if ((ciabcrb & 0x61) == 0x41) {
  195.     /* Timer B will not get any pulses if Timer A is off. */
  196.     if (ciabtimea >= 0) {
  197.         /* If Timer A is in one-shot mode, and Timer B needs more than
  198.          * one pulse, it will not underflow. */
  199.         if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
  200.         /* Otherwise, we can determine the time of the underflow. */
  201.         ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
  202.         }
  203.     }
  204.     }
  205.     if ((ciabcrb & 0x61) == 0x01) {
  206.     ciabtimeb = (DIV10-div10) + DIV10*ciabtb;
  207.     }
  208.     eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
  209.                    || ciabtimea != -1 || ciabtimeb != -1);
  210.     if (eventtab[ev_cia].active) {
  211.     unsigned long int ciatime = ~0L;
  212.     if (ciaatimea != -1) ciatime = ciaatimea;
  213.     if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
  214.     if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
  215.     if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
  216.     eventtab[ev_cia].evtime = ciatime + cycles;
  217.     }
  218.     events_schedule();
  219. }
  220.  
  221. void CIA_handler(void)
  222. {
  223.     CIA_update();
  224.     CIA_calctimers();
  225. }
  226.  
  227. void diskindex_handler(void)
  228. {
  229.     eventtab[ev_diskindex].evtime += cycles - eventtab[ev_diskindex].oldcycles;
  230.     eventtab[ev_diskindex].oldcycles = cycles;
  231. /*    printf(".\n");*/
  232.     ciabicr |= 0x10;
  233.     RethinkICRB();
  234. }
  235.  
  236. void CIA_hsync_handler(void)
  237. {
  238.     static unsigned int keytime = 0, sleepyhead = 0;
  239.  
  240.     if (ciabtodon)
  241.     ciabtod++;
  242.     ciabtod &= 0xFFFFFF;
  243.  
  244.     if (ciabtod == ciabalarm) {
  245.     ciabicr |= 4; RethinkICRB();
  246.     }
  247.  
  248.     SERDATS();    /*  check if the serial Port gets some data  */
  249.  
  250.     if (keys_available() && kback && (++keytime & 15) == 0) {
  251.         /*
  252.      * This hack lets one possible ciaaicr cycle go by without any key
  253.      * being read, for every cycle in which a key is pulled out of the
  254.      * queue.  If no hack is used, a lot of key events just get lost
  255.      * when you type fast.  With a simple hack that waits for ciaasdr
  256.      * to be read before feeding it another, it will keep up until the
  257.      * queue gets about 14 characters ahead and then lose events, and
  258.      * the mouse pointer will freeze while typing is being taken in.
  259.      * With this hack, you can type 30 or 40 characters ahead with little
  260.      * or no lossage, and the mouse doesn't get stuck.  The tradeoff is
  261.      * that the total slowness of typing appearing on screen is worse.
  262.      */
  263.         if (ciaasdr_unread == 2)
  264.             ciaasdr_unread = 0;
  265.         else if (ciaasdr_unread == 0) {
  266.             switch (kbstate) {
  267.          case 0:
  268.             ciaasdr = (uae_s8)~0xFB; /* aaarghh... stupid compiler */
  269.             kbstate++;
  270.             break;
  271.          case 1:
  272.             kbstate++;
  273.             ciaasdr = (uae_s8)~0xFD;
  274.             break;
  275.          case 2:
  276.             ciaasdr = ~get_next_key();
  277.             ciaasdr_unread = 1;      /* interlock to prevent lost keystrokes */
  278.             break;
  279.         }
  280.         ciaaicr |= 8;
  281.         RethinkICRA();
  282.         sleepyhead = 0;
  283.         } else if (!(++sleepyhead & 15))
  284.             ciaasdr_unread = 0;          /* give up on this key event after unread for a long time */
  285.     }
  286. }
  287.  
  288. void CIA_vsync_handler()
  289. {    
  290.     if (ciaatodon) 
  291.     ciaatod++;
  292.     ciaatod &= 0xFFFFFF;
  293.     if (ciaatod == ciaaalarm) {
  294.     ciaaicr |= 4; RethinkICRA();
  295.     }
  296. }
  297.  
  298. static uae_u8 ReadCIAA(unsigned int addr)
  299. {
  300.     unsigned int tmp;
  301.     
  302.     switch(addr & 0xf){
  303.      case 0: 
  304.     tmp = (DISK_status() & 0x3C);
  305.     if ((JSEM_ISMOUSE (0, currprefs.fake_joystick) && !buttonstate[0])
  306.         || (!JSEM_ISMOUSE (0, currprefs.fake_joystick) && !(joy0button & 1)))
  307.         tmp |= 0x40;
  308.     if (!(joy1button & 1))
  309.         tmp |= 0x80;
  310.     return tmp;
  311.      case 1:
  312.     return ciaaprb;
  313.      case 2:
  314.     return ciaadra;
  315.      case 3:
  316.     return ciaadrb;
  317.      case 4:
  318.     return ciaata & 0xff;
  319.      case 5:
  320.     return ciaata >> 8;
  321.      case 6:
  322.     return ciaatb & 0xff;
  323.      case 7:
  324.     return ciaatb >> 8;
  325.      case 8:
  326.     if (ciaatlatch) {
  327.         ciaatlatch = 0;
  328.         return ciaatol & 0xff;
  329.     } else
  330.         return ciaatod & 0xff;
  331.      case 9:
  332.     if (ciaatlatch)
  333.         return (ciaatol >> 8) & 0xff;
  334.     else
  335.         return (ciaatod >> 8) & 0xff;
  336.      case 10:
  337.     ciaatlatch = 1;
  338.     ciaatol = ciaatod; /* ??? only if not already latched? */
  339.     return (ciaatol >> 16) & 0xff;
  340.      case 12:
  341.         if (ciaasdr == 1) ciaasdr_unread = 2;
  342.     return ciaasdr;
  343.      case 13:
  344.     tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp;
  345.      case 14:
  346.     return ciaacra;
  347.      case 15:
  348.     return ciaacrb;
  349.     }
  350.     return 0;
  351. }
  352.  
  353. static uae_u8 ReadCIAB(unsigned int addr)
  354. {
  355.     unsigned int tmp;
  356.     
  357.     switch(addr & 0xf){
  358.      case 0: 
  359.     return ciabpra;
  360.      case 1:
  361.     return ciabprb;
  362.      case 2:
  363.     return ciabdra;
  364.      case 3:
  365.     return ciabdrb;
  366.      case 4:
  367.     return ciabta & 0xff;
  368.      case 5:
  369.     return ciabta >> 8;
  370.      case 6:
  371.     return ciabtb & 0xff;
  372.      case 7:
  373.     return ciabtb >> 8;
  374.      case 8:
  375.     if (ciabtlatch) {
  376.         ciabtlatch = 0;
  377.         return ciabtol & 0xff;
  378.     } else
  379.         return ciabtod & 0xff;
  380.      case 9:
  381.     if (ciabtlatch)
  382.         return (ciabtol >> 8) & 0xff;
  383.     else
  384.         return (ciabtod >> 8) & 0xff;
  385.      case 10:
  386.     ciabtlatch = 1;
  387.     ciabtol = ciabtod;
  388.     return (ciabtol >> 16) & 0xff;
  389.      case 12:
  390.     return ciabsdr;
  391.      case 13:
  392.     tmp = ciabicr; ciabicr = 0; RethinkICRB();
  393.     return tmp;
  394.      case 14:
  395.     return ciabcra;
  396.      case 15:
  397.     return ciabcrb;
  398.     }
  399.     return 0;
  400. }
  401.  
  402. static void WriteCIAA(uae_u16 addr,uae_u8 val)
  403. {
  404.     int oldled, oldovl;
  405.     switch(addr & 0xf){
  406.      case 0:
  407.     oldovl = ciaapra & 1;
  408.     oldled = ciaapra & 2;
  409.     ciaapra = (ciaapra & ~0x3) | (val & 0x3); LED(ciaapra & 0x2);
  410.     if ((ciaapra & 2) != oldled)
  411.         gui_led (0, !(ciaapra & 2));
  412.     if ((ciaapra & 1) != oldovl) {
  413.         map_banks(oldovl ? &chipmem_bank : &kickmem_bank, 0, 32);
  414.     }
  415.     break;
  416.      case 1:
  417.     ciaaprb = val;
  418.     if (prtopen==1) {
  419. #ifndef __DOS__
  420.         fprintf (prttmp,"%c",val);
  421. #else
  422.         fputc (val, prttmp);
  423.         fflush (prttmp);
  424. #endif
  425.         if (val==0x04) {
  426. #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
  427.         pclose (prttmp);
  428. #else
  429.         fclose (prttmp);
  430. #endif
  431.         prtopen = 0;
  432.         }
  433.         } else {
  434. #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
  435.             prttmp=(FILE *)popen ((char *)prtname,"w");
  436. #else
  437.             prttmp=(FILE *)fopen ((char *)prtname,"wb");
  438. #endif
  439.         if (prttmp != NULL) {
  440.         prtopen = 1;
  441. #ifndef __DOS__
  442.         fprintf (prttmp,"%c",val);
  443. #else
  444.         fputc (val, prttmp);
  445.         fflush (prttmp);
  446. #endif
  447.         }
  448.         }
  449.     ciaaicr |= 0x10;
  450.     break;
  451.      case 2:
  452.     ciaadra = val; break;
  453.      case 3:
  454.     ciaadrb = val; break;
  455.      case 4:
  456.     CIA_update();
  457.     ciaala = (ciaala & 0xff00) | val;
  458.     CIA_calctimers();
  459.     break;
  460.      case 5:
  461.     CIA_update();
  462.     ciaala = (ciaala & 0xff) | (val << 8);
  463.     if ((ciaacra & 1) == 0)
  464.         ciaata = ciaala;
  465.     if (ciaacra & 8) { 
  466.         ciaata = ciaala; 
  467.         ciaacra |= 1; 
  468.     }
  469.     CIA_calctimers();
  470.     break;
  471.      case 6:
  472.     CIA_update();
  473.     ciaalb = (ciaalb & 0xff00) | val;
  474.     CIA_calctimers();
  475.     break;
  476.      case 7:
  477.     CIA_update();
  478.     ciaalb = (ciaalb & 0xff) | (val << 8);
  479.     if ((ciaacrb & 1) == 0)
  480.         ciaatb = ciaalb;
  481.     if (ciaacrb & 8) { 
  482.         ciaatb = ciaalb;
  483.         ciaacrb |= 1; 
  484.     }
  485.     CIA_calctimers();
  486.     break;
  487.      case 8:
  488.     if (ciaacrb & 0x80){
  489.         ciaaalarm = (ciaaalarm & ~0xff) | val;
  490.     } else {
  491.         ciaatod = (ciaatod & ~0xff) | val;
  492.         ciaatodon = 1;
  493.     }
  494.     break;
  495.      case 9:
  496.     if (ciaacrb & 0x80){
  497.         ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
  498.     } else {
  499.         ciaatod = (ciaatod & ~0xff00) | (val << 8);
  500.         ciaatodon = 0;
  501.     }
  502.     break;
  503.      case 10:
  504.     if (ciaacrb & 0x80){
  505.         ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
  506.     } else {
  507.         ciaatod = (ciaatod & ~0xff0000) | (val << 16);
  508.         ciaatodon = 0;
  509.     }
  510.     break;
  511.      case 12:
  512.     ciaasdr = val; break;
  513.      case 13:
  514.     setclr(&ciaaimask,val); break; /* ??? call RethinkICR() ? */
  515.      case 14:
  516.     CIA_update();
  517.     ciaacra = val;
  518.     if (ciaacra & 0x10){
  519.         ciaacra &= ~0x10;
  520.         ciaata = ciaala;
  521.     }
  522.     if (ciaacra & 0x40) {
  523.         kback = 1;
  524.     }
  525.     CIA_calctimers();
  526.     break;
  527.      case 15:
  528.     CIA_update();
  529.     ciaacrb = val; 
  530.     if (ciaacrb & 0x10){
  531.         ciaacrb &= ~0x10;
  532.         ciaatb = ciaalb;
  533.     }
  534.     CIA_calctimers();
  535.     break;
  536.     }
  537. }
  538.  
  539. static void WriteCIAB(uae_u16 addr,uae_u8 val)
  540. {
  541.     int remember;
  542.     switch(addr & 0xf){
  543.      case 0:
  544.         remember=ciabpra;
  545.     ciabpra  = val;
  546.         ciabpra |= 0x80;
  547.  
  548.         if (((remember&0x40)==0x40) && ((ciabpra&0x40)==0x00)) 
  549.           fprintf (stdout,"RTS cleared.\n");
  550.         if (((remember&0x40)==0x00) && ((ciabpra&0x40)==0x40))
  551.           fprintf (stdout,"RTS set.\n");
  552.         if (((remember&0x10)==0x10) && ((ciabpra&0x10)==0x00))
  553.           fprintf (stdout,"CTS cleared.\n");
  554.         if (((remember&0x10)==0x00) && ((ciabpra&0x10)==0x10))
  555.           fprintf (stdout,"CTS set.\n");
  556.  
  557.     break;
  558.      case 1:
  559.     ciabprb = val; DISK_select(val); break;
  560.      case 2:
  561.     ciabdra = val; break;
  562.      case 3:
  563.     ciabdrb = val; break;
  564.      case 4:
  565.     CIA_update();
  566.     ciabla = (ciabla & 0xff00) | val;
  567.     CIA_calctimers();
  568.     break;
  569.      case 5:
  570.     CIA_update();
  571.     ciabla = (ciabla & 0xff) | (val << 8);
  572.     if ((ciabcra & 1) == 0) 
  573.         ciabta = ciabla;
  574.     if (ciabcra & 8) {
  575.         ciabta = ciabla; 
  576.         ciabcra |= 1; 
  577.     } 
  578.     CIA_calctimers();
  579.     break;
  580.      case 6:
  581.     CIA_update();
  582.     ciablb = (ciablb & 0xff00) | val;
  583.     CIA_calctimers();
  584.     break;
  585.      case 7:
  586.     CIA_update();
  587.     ciablb = (ciablb & 0xff) | (val << 8);
  588.     if ((ciabcrb & 1) == 0)
  589.         ciabtb = ciablb;
  590.     if (ciabcrb & 8) {
  591.         ciabtb = ciablb;
  592.         ciabcrb |= 1;
  593.     }
  594.     CIA_calctimers();
  595.     break;
  596.      case 8:
  597.     if (ciabcrb & 0x80){
  598.         ciabalarm = (ciabalarm & ~0xff) | val;
  599.     } else {
  600.         ciabtod = (ciabtod & ~0xff) | val;
  601.         ciabtodon = 1;
  602.     }
  603.     break;
  604.      case 9:
  605.     if (ciabcrb & 0x80){
  606.         ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
  607.     } else {
  608.         ciabtod = (ciabtod & ~0xff00) | (val << 8);
  609.         ciabtodon = 0;
  610.     }
  611.     break;
  612.      case 10:
  613.     if (ciabcrb & 0x80){
  614.         ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
  615.     } else {
  616.         ciabtod = (ciabtod & ~0xff0000) | (val << 16);
  617.         ciabtodon = 0;
  618.     }
  619.     break;
  620.      case 12:
  621.     ciabsdr = val; 
  622.     break;
  623.      case 13:
  624.     setclr(&ciabimask,val); 
  625.     break;
  626.      case 14:
  627.     CIA_update();
  628.     ciabcra = val;
  629.     if (ciabcra & 0x10){
  630.         ciabcra &= ~0x10;
  631.         ciabta = ciabla;
  632.     }
  633.     CIA_calctimers();
  634.     break;
  635.      case 15:
  636.     CIA_update();
  637.     ciabcrb = val; 
  638.     if (ciabcrb & 0x10){
  639.         ciabcrb &= ~0x10;
  640.         ciabtb = ciablb;
  641.     }
  642.     CIA_calctimers();
  643.     break;
  644.     }
  645. }
  646.  
  647. uae_u8 CIA_shakehands_get(void)
  648. {
  649.    return ciabpra;
  650. }
  651. void CIA_shakehands_set(uae_u8 mask)
  652. {
  653.    ciabpra |= mask;
  654. }
  655. void CIA_shakehands_clear(uae_u8 mask)
  656. {
  657.    ciabpra &= ~mask;
  658. }
  659.  
  660. void CIA_reset(void)
  661. {
  662.     kback = 1;
  663.     kbstate = 0;
  664.     
  665.     ciaatlatch = ciabtlatch = 0;
  666.     ciaapra = 2;
  667.     ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
  668.     ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
  669.     ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
  670.     ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
  671.     div10 = 0;
  672.     lastdiv10 = 0;
  673.     CIA_calctimers();
  674.     ciabpra = 0x8C;
  675.     /*fprintf (stderr," CIA-Reset\n ");*/
  676. }
  677.  
  678. void dumpcia(void)
  679. {
  680.     printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  681.        (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod, 
  682.        ciaatlatch ? " latched" : "", ciaata, ciaatb);
  683.     printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  684.        (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod, 
  685.        ciabtlatch ? " latched" : "", ciabta, ciabtb);
  686. }
  687.  
  688. /* CIA memory access */
  689.  
  690. static uae_u32 cia_lget(uaecptr) REGPARAM;
  691. static uae_u32 cia_wget(uaecptr) REGPARAM;
  692. static uae_u32 cia_bget(uaecptr) REGPARAM;
  693. static void  cia_lput(uaecptr, uae_u32) REGPARAM;
  694. static void  cia_wput(uaecptr, uae_u32) REGPARAM;
  695. static void  cia_bput(uaecptr, uae_u32) REGPARAM;
  696.  
  697. addrbank cia_bank = {
  698.     cia_lget, cia_wget, cia_bget,
  699.     cia_lput, cia_wput, cia_bput,
  700.     default_xlate, default_check
  701. };
  702.  
  703. uae_u32 REGPARAM2 cia_lget(uaecptr addr)
  704. {
  705.     return cia_bget(addr+3);
  706. }
  707.  
  708. uae_u32 REGPARAM2 cia_wget(uaecptr addr)
  709. {
  710.     return cia_bget(addr+1);
  711. }
  712.  
  713. uae_u32 REGPARAM2 cia_bget(uaecptr addr)
  714. {
  715.     if ((addr & 0x3001) == 0x2001)
  716.         return ReadCIAA((addr & 0xF00) >> 8);
  717.     if ((addr & 0x3001) == 0x1000)
  718.         return ReadCIAB((addr & 0xF00) >> 8);
  719.     return 0;
  720. }
  721.  
  722. void REGPARAM2 cia_lput(uaecptr addr, uae_u32 value)
  723. {
  724.     cia_bput(addr+3,value); /* FIXME ? */
  725. }
  726.  
  727. void REGPARAM2 cia_wput(uaecptr addr, uae_u32 value)
  728. {
  729.     cia_bput(addr+1,value);
  730. }
  731.  
  732. void REGPARAM2 cia_bput(uaecptr addr, uae_u32 value)
  733. {
  734.     if ((addr & 0x3001) == 0x2001)
  735.         WriteCIAA((addr & 0xF00) >> 8,value);
  736.     if ((addr & 0x3001) == 0x1000)
  737.         WriteCIAB((addr & 0xF00) >> 8,value);
  738. }
  739.  
  740. /* battclock memory access */
  741.  
  742. static uae_u32 clock_lget(uaecptr) REGPARAM;
  743. static uae_u32 clock_wget(uaecptr) REGPARAM;
  744. static uae_u32 clock_bget(uaecptr) REGPARAM;
  745. static void  clock_lput(uaecptr, uae_u32) REGPARAM;
  746. static void  clock_wput(uaecptr, uae_u32) REGPARAM;
  747. static void  clock_bput(uaecptr, uae_u32) REGPARAM;
  748.  
  749. addrbank clock_bank = {
  750.     clock_lget, clock_wget, clock_bget,
  751.     clock_lput, clock_wput, clock_bput,
  752.     default_xlate, default_check
  753. };
  754.  
  755. uae_u32 REGPARAM2 clock_lget(uaecptr addr)
  756. {
  757.     return clock_bget(addr+3);
  758. }
  759.  
  760. uae_u32 REGPARAM2 clock_wget(uaecptr addr)
  761. {
  762.     return clock_bget(addr+1);
  763. }
  764.  
  765. uae_u32 REGPARAM2 clock_bget(uaecptr addr)
  766. {
  767.     time_t t=time(0);
  768.     struct tm *ct;
  769.     ct=localtime(&t);
  770.     switch (addr & 0x3f)
  771.     {
  772.      case 0x03: return ct->tm_sec % 10;
  773.      case 0x07: return ct->tm_sec / 10;
  774.      case 0x0b: return ct->tm_min % 10;
  775.      case 0x0f: return ct->tm_min / 10;
  776.      case 0x13: return ct->tm_hour % 10;
  777.      case 0x17: return ct->tm_hour / 10;
  778.      case 0x1b: return ct->tm_mday % 10;
  779.      case 0x1f: return ct->tm_mday / 10;
  780.      case 0x23: return (ct->tm_mon+1) % 10;
  781.      case 0x27: return (ct->tm_mon+1) / 10;
  782.      case 0x2b: return ct->tm_year % 10;
  783.      case 0x2f: return ct->tm_year / 10;
  784.  
  785.      case 0x33: return ct->tm_wday;  /*Hack by -=SR=- */
  786.      case 0x37: return clock_control_d;
  787.      case 0x3b: return clock_control_e;
  788.      case 0x3f: return clock_control_f;
  789.     }
  790.     return 0;
  791. }
  792.  
  793. void REGPARAM2 clock_lput(uaecptr addr, uae_u32 value)
  794. {
  795.     /* No way */
  796. }
  797.  
  798. void REGPARAM2 clock_wput(uaecptr addr, uae_u32 value)
  799. {
  800.     /* No way */
  801. }
  802.  
  803. void REGPARAM2 clock_bput(uaecptr addr, uae_u32 value)
  804. {
  805.     switch (addr & 0x3f)
  806.     {
  807.      case 0x37: clock_control_d=value; break;
  808.      case 0x3b: clock_control_e=value; break;
  809.      case 0x3f: clock_control_f=value; break;
  810.     }
  811. }
  812.